﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Linq;
using Dsl.Ped.Editor.Interfaces;
using Dsl.Ped.Framework.AddIns;

namespace Dsl.Ped.Editor
{
    /// <summary>
    /// Interaction logic for DslPedEditor.xaml
    /// </summary>
    public partial class DslPedEditor : IDslPedEditor
    {
        #region Fields

        /// <summary>
        /// View model of the editor
        /// </summary>
        private DslPedEditorViewModel viewModel;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="DslPedEditor"/> class. 
        /// </summary>
        /// <param name="editorAddIns">The editor add-ins metadata</param>
        public DslPedEditor(IEnumerable<Lazy<IDslPedAddIn, IDslPedAddInMetadata>> editorAddIns)
        {
            InitializeComponent();
            this.ViewModel = new DslPedEditorViewModel(editorAddIns);
        }

        #endregion

        #region Members

        /// <summary>
        /// Gets the dictionary of registered add-ins, namespace to the projective type
        /// </summary>
        public Dictionary<string, Type> RegisteredTypes
        {
            get { return ViewModel.RegisteredTypes; }
        }

        /// <summary>
        /// Gets the currently opened file 
        /// </summary>
        public string CurrentFileName
        {
            get { return ViewModel.CurrentFileName; }
        }

        /// <summary>
        /// Gets the current projective type
        /// </summary>
        public Type CurrentProjectiveType
        {
            get { return ViewModel.CurrentProjectiveType; }
        }

        /// <summary>
        /// Gets the indication that a projective object was changed in the editor
        /// </summary>
        public bool IsDirty
        {
            get { return viewModel.IsDirty; }
            set { viewModel.IsDirty = value; }
        }

        /// <summary>
        /// Gets or sets a View model of <see cref="DslPedEditor"/>
        /// </summary>
        private DslPedEditorViewModel ViewModel
        {
            get
            {
                return this.viewModel;
            }
            set
            {
                this.viewModel = value;
                DataContext = this.viewModel;
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Loads the file of a given <see cref="fileName"/> name
        /// </summary>
        /// <param name="fileName">Name of the file to be loaded</param>
        /// <returns>Projective object deserialized from the file of a given <see cref="fileName"/></returns>
        public object LoadFile(string fileName)
        {
            return viewModel.LoadFile(fileName);
        }

        /// <summary>
        /// Loads the file of a given name, use the <see cref="XmlReader"/> for the deserialization into
        /// the projective object.
        /// </summary>
        /// <param name="fileName">Name of the file to be loaded</param>
        /// <param name="xmlReader"><see cref="XmlReader"/> used for the deserialization of a file</param>
        /// <returns>Projective object deserialized from the <see cref="fileName"/> file using the given <see cref="xmlReader"/></returns>
        public object LoadFile(string fileName, XmlReader xmlReader)
        {
            return viewModel.LoadFile(fileName, xmlReader);
        }

        /// <summary>
        /// Open the currently loaded file
        /// </summary>
        public void OpenLoadedFile()
        {
            viewModel.OpenLoadedFile();
        }

        /// <summary>
        /// Load and open a given file into the editor
        /// </summary>
        /// <param name="fileName">Name of the file to be loaded</param>
        public void LoadAndOpenFile(string fileName)
        {
            ViewModel.LoadAndOpenFile(fileName);
        }

        /// <summary>
        /// Load and open a given file into the editor, use the given <see cref="XmlReader"/> for the deserialization
        /// into the projective object.
        /// </summary>
        /// <param name="fileName">Name of the file to be loaded</param>
        /// <param name="xmlReader"><see cref="XmlReader"/> used for the deserialization</param>
        public void LoadAndOpenFile(string fileName, XmlReader xmlReader)
        {
            ViewModel.LoadAndOpenFile(fileName, xmlReader);
        }

        /// <summary>
        /// Save the current projective object under the current file name
        /// </summary>
        /// <returns></returns>
        public bool SaveFile()
        {
            return viewModel.SaveFile();
        }

        /// <summary>
        /// Save the current projective object under the given file name
        /// </summary>
        /// <param name="fileName">Name of the file</param>
        /// <returns>True if the save was successfull, False otherwise</returns>
        public bool SaveFile(string fileName)
        {
            return viewModel.SaveFile(fileName);
        }

        /// <summary>
        /// Create new projective object of a given type
        /// </summary>
        /// <param name="projectiveType">Required type of the projective object</param>
        /// <returns>True if the creation was successfull, False otherwise</returns>
        public bool NewProjectiveObject(Type projectiveType)
        {
            return viewModel.NewProjectiveObject(projectiveType);
        }

        /// <summary>
        /// Create new projective object of a given projective type, use the default instance if not null
        /// </summary>
        /// <param name="projectiveType">Required type of the projective object</param>
        /// <param name="defaultObject">Default instance of the projective type.</param>
        /// <returns>True if the object was created successfully, False otherwise</returns>
        public bool NewProjectiveObject(Type projectiveType, object defaultObject)
        {
            return viewModel.NewProjectiveObject(projectiveType, defaultObject);
        }

        /// <summary>
        /// Serialize current projective object into the <see cref="XDocument"/>
        /// </summary>
        /// <returns><see cref="XDocument"/> that the current projective object was serialized to</returns>
        public XDocument SerializeProjectiveObject()
        {
            return viewModel.SerializeProjectiveObject();
        }

        #endregion
    }
}
